package com.shop.config.webSocket;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shop.common.BeanUtil;
import com.shop.dto.WebSocketDto;
import com.shop.entity.ClientDo;
import com.shop.entity.WebSocketDo;
import com.shop.mapper.ClientDoMapper;
import com.shop.shopEnum.YesOrNoEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

@Slf4j
@Component
@Data
@ServerEndpoint(value = "/websocket/{clientId}")
public class WebSocketService {

    private Session session;


    //存放客户端对应 WebSocketService 对象
    private static final CopyOnWriteArraySet<WebSocketService> webSocketSet = new CopyOnWriteArraySet<WebSocketService>();


    private static final Map<String,ClientDo> saveOnLinePeoPle = new HashMap<>();

    private Long clientId;

    /**
     * 打开
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("clientId") String clientId)throws Exception {
        this.session = session;
        this.clientId = Long.valueOf(clientId);
        webSocketSet.add(this);//加入set中'
        ClientDoMapper clientDoMapper = BeanUtil.getBeanByBeanName("clientDoMapper",ClientDoMapper.class);
        ClientDo clientDo = clientDoMapper.selectById(clientId);
        WebSocketDto webSocketDto = new WebSocketDto();
        webSocketDto.setPkClientId(clientDo.getPkClientId());
        webSocketDto.setClientName(clientDo.getClientName());
        webSocketDto.setHeadImage(clientDo.getHeadPortrait());
        webSocketDto.setNumberOfPeopleOnline(webSocketSet.size());
        webSocketDto.setIsOfPeopleOnlineRemind(YesOrNoEnum.YES.code);
        saveOnLinePeoPle.putIfAbsent(clientDo.getPkClientId().toString(),clientDo);
        webSocketDto.setSaveOnLinePeoPle(saveOnLinePeoPle);
        WebSocketService.broadcast(webSocketDto);
    }


    /**
     * 关闭
     */
    @OnClose
    public void onClose(Session session) throws Exception {
        try {
            log.info(webSocketSet.toString());
            webSocketSet.remove(this);
            saveOnLinePeoPle.keySet().removeIf(key -> key.equals(this.clientId.toString()));
            log.info(saveOnLinePeoPle.size()+"");
            WebSocketDto webSocketDto = new WebSocketDto();
            webSocketDto.setNumberOfPeopleOnline(saveOnLinePeoPle.size());
            webSocketDto.setIsOfPeopleOnlineRemind(YesOrNoEnum.YES.code);
            webSocketDto.setSaveOnLinePeoPle(saveOnLinePeoPle);
            WebSocketService.broadcast(webSocketDto);
            session.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 接收消息
     *
     * @param vo
     */
    @OnMessage
    public void onMessage(String vo)throws Exception {
        WebSocketDo webSocketDo = JSON.parseObject(vo, WebSocketDo.class);
        log.info("---------------------->{},{}", webSocketDo.getClientId(), webSocketDo.getContent());
        ClientDoMapper clientDoMapper = BeanUtil.getBeanByBeanName("clientDoMapper",ClientDoMapper.class);
        ClientDo clientDo = clientDoMapper.selectById(webSocketDo.getClientId());
        WebSocketDto webSocketDto = new WebSocketDto();
        webSocketDto.setPkClientId(clientDo.getPkClientId());
        webSocketDto.setClientName(clientDo.getClientName());
        webSocketDto.setHeadImage(clientDo.getHeadPortrait());
        webSocketDto.setContent(webSocketDo.getContent());
        webSocketDto.setNumberOfPeopleOnline(webSocketSet.size());
        webSocketDto.setIsOfPeopleOnlineRemind(YesOrNoEnum.NO.code);
        WebSocketService.broadcast(webSocketDto);
    }


    /**
     * 错误回调
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        try {
            webSocketSet.remove(this);
            session.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 群发自定义消息
     *
     * @param message
     */
    public static void broadcast(Object message) {
        String messages = JSONObject.toJSONString(message);
        for (WebSocketService item : webSocketSet) {
            item.session.getAsyncRemote().sendText(messages);//异步发送消息.
        }
    }

}
